#pragma once

// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// TextureLayer.h : interface of the TextureLayer class
//

class Texture;


// ----------------------------------------------------------------------------


BEGIN_ENUM(EnvironmentMode)
    Modulate = GL_MODULATE, 
    Decal = GL_DECAL, 
    Blend = GL_BLEND, 
    Replace = GL_REPLACE,
    Add = GL_ADD,
    Combine = GL_COMBINE
END_ENUM(EnvironmentMode);

BEGIN_ENUM(RgbCombinationMode)
    AlphaInterpolation = GL_INTERPOLATE,
    Modulate = GL_MODULATE,
    Replace = GL_REPLACE,
    Add = GL_ADD,
    AddSigned = GL_ADD_SIGNED,
    Subtract = GL_SUBTRACT
END_ENUM(RgbCombinationMode);

BEGIN_ENUM(AlphaCombinationMode)
    Modulate = GL_MODULATE,
    Replace = GL_REPLACE,
    Add = GL_ADD,
    AddSigned = GL_ADD_SIGNED,
    Subtract = GL_SUBTRACT
END_ENUM(AlphaCombinationMode);

BEGIN_ENUM(PrimaryColorMode)
    ApplyFirst,
    ApplyLast,
    DontApply
END_ENUM(PrimaryColorMode)

BEGIN_ENUM(TextureWrapMode)
    Repeat = GL_REPEAT,
    MirroredRepeat = GL_MIRRORED_REPEAT,
    Clamp = GL_CLAMP,
    ClampToBorder = GL_CLAMP_TO_BORDER,
    ClampToEdge = GL_CLAMP_TO_EDGE,
END_ENUM(TextureWrapMode)


class TextureLayer : public Selectable 
{
public:

    TextureLayer();

    void setTexture(ref<Texture> tex);
    Texture* getTexture() const;

    void setEnvMode(EnvironmentMode mode);
    void setRgbCombiMode(RgbCombinationMode mode);
    void setAlphaCombiMode(AlphaCombinationMode mode);

    EnvironmentMode getEnvMode() const;
    RgbCombinationMode getRgbCombiMode() const;
    AlphaCombinationMode getAlphaCombiMode() const;

    void setBorderColor(const Color& color);
    Color getBorderColor() const;
    
    void setSWrapMode(TextureWrapMode mode);
    void setTWrapMode(TextureWrapMode mode);

    TextureWrapMode getSWrapMode() const;
    TextureWrapMode getTWrapMode() const;

    void setMaterial(Material* mat);
    Material* getMaterial();

    // To be used internally by the associated Material
    void setInRenderContext() const;

private:


    void notify();

    ref<Texture> texture;
    EnvironmentMode envMode;
    RgbCombinationMode rgbCombiMode;
    AlphaCombinationMode alphaCombiMode;

    Color borderColor; // black by default

    TextureWrapMode sWrapMode; // repeat by default
    TextureWrapMode tWrapMode; // repeat by default

    Material* owner;
    std::wstring getName() const;
};


typedef std::vector<ref<TextureLayer> > TextureLayerList;

